using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class VisionManager : MonoBehaviour {

    private static VisionManager instance;
    static public VisionManager GetInstance()
    {
        return instance;
    }

    //TO DO: Hacer un pool
    public GameObject SoundEffectPrefab;
    public float VisionAngle = 45;
    public float ShortRange = 5;
    public float LongRange = 8;


    public int rayAmount = 30;
    bool m_ShowSoundVisual = true;

    Enemy m_SelectedEnemy = null;

    public VolumetricLight[] visionCones = new VolumetricLight[2];

    private Pool m_SoundEffectPool;



    List<Character> m_Characters = new List<Character>();
    List<Enemy> m_AliveEnemies = new List<Enemy>();
    List<Enemy> m_DeadEnemies = new List<Enemy>();
	void Awake () 
    {
        instance = this;
        visionCones[0].CreateMesh(rayAmount);
        visionCones[1].CreateMesh(rayAmount);
	}
    void Start()
    {
        m_SoundEffectPool = PrefabManager.GetInstance().GetPool("soundwave");
    }
	void Update () 
    {

	}
    void FixedUpdate()
    {
        if (m_SelectedEnemy != null)
        {
            UpdateVisionCone();
        }
    }

#region VisionCone

    public void UpdateVisionCone()
    {
        //Debug.Log(m_SelectedEnemy.GetEyeDirection());
        visionCones[0].UpdateVertices(m_SelectedEnemy.transform.position+ Vector3.up,
            m_SelectedEnemy.GetEyeDirection(), VisionAngle, ShortRange, Vector3.up);

        visionCones[1].UpdateVertices(m_SelectedEnemy.transform.position+Vector3.up/2,
            m_SelectedEnemy.GetEyeDirection(), VisionAngle, LongRange, Vector3.up);
    }
    /// <summary>
    /// Selecciona a un enemigo haciendo que se vea su rango de vision. Si ya esta seleccionado lo deselecciona.
    /// </summary>
    /// <param name="enemy"></param>
    public void SelectEnemy(Enemy enemy)
    {
        //si ya esta seleccionado lo deselecciono.
        if (enemy == m_SelectedEnemy)
        {
            DeSelectEnemy();
            return;
        }
        m_SelectedEnemy = enemy;
        visionCones[0].renderer.enabled = true;
        visionCones[1].renderer.enabled = true;
    }
    public void DeSelectEnemy()
    {
        m_SelectedEnemy = null;
        visionCones[0].renderer.enabled = false;
        visionCones[1].renderer.enabled = false;
    }
    public Enemy GetSelectedEnemy()
    {
        return m_SelectedEnemy;
    }

#endregion
    public List<Character> GetCharacters(Vector3 position)
    {
        return m_Characters;
    }
    public List<Enemy> GetDeadEnemies()
    {
        return m_DeadEnemies;
    }
    /// <summary>
    /// Saca al enemigo que se murio de la lista de vivos y lo pone en la de muertos.
    /// </summary>
    /// <param name="enemy">Enemigo que se murio</param>
    public void OnEnemyDeath(Enemy enemy)
    {
        m_AliveEnemies.Remove(enemy);
        m_DeadEnemies.Add(enemy);
    }
    public void AddCharacter(Character character)
    {
        m_Characters.Add(character);
    }
    /// <summary>
    /// Genera sonido (logica) para los enemigos.
    /// </summary>
    /// <param name="position">Posicion de donde sale el sonido.</param>
    /// <param name="radius">Radio que tiene.</param>
    public void GenerateSound(Vector3 position, float radius)
    {
        foreach (Enemy e in m_AliveEnemies)
        {
            if (Vector3.Distance(e.transform.position, position) <= radius)
            {
                e.RecieveSound(position);
            }
        }
        if (m_ShowSoundVisual)
        {
            CreateSoundVisual(position, radius);
        }
    }
    public void ToggleSoundVisual()
    {
        Debug.Log("Sound effects visual activated/deactivated");
        m_ShowSoundVisual = !m_ShowSoundVisual;
    }
    public bool IsSoundVisualActive()
    {
        return m_ShowSoundVisual;
    }
    public void CreateSoundVisual(Vector3 position, float radius)
    {
        //SoundWaveEffect sw = ((GameObject)(GameObject.Instantiate(SoundEffectPrefab))).GetComponent<SoundWaveEffect>();
        SoundWaveEffect sw = m_SoundEffectPool.Create().GetComponent<SoundWaveEffect>();
        //sw.StartEffect(position, radius, 15);
        sw.StartEffect(1, radius, position);
    }
    public void RegisterEnemy(Enemy enemy)
    {
        m_AliveEnemies.Add(enemy);
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="row">row anterior</param>
    /// <param name="col">col anterior</param>
    /// <param name="enemy">Enemigo a actualizar la posicion</param>
    public void UpdateGridPosition(int row, int col, Enemy enemy)
    {
 
    }
}
